# coding:utf-8
'''
@version: python3
@author: ‘eric‘
@license: Apache Licence
@contact: steinven@qq.com
@software: PyCharm
@file: tt.py
@time: 2023-10-16 18:03
'''
import hashlib
import os
import time

import requests
from loguru import logger

MAX_RETRY_ATTEMPTS = 200

def open_request(path, data, token):
    url = 'https://open-api.123pan.com' + path
    headers = {
        'Content-Type': 'application/json',
        'Platform': 'open_platform',
        'Authorization': 'Bearer ' + token
    }

    try:
        response = requests.post(url, data=data, headers=headers)
        response.raise_for_status()
        res = response.json()

        if 'code' not in res or res['code'] != 0:
            message = res.get('message', 'Network error')
            raise Exception(message)

        return res.get('data')

    except requests.exceptions.RequestException as e:
        logger.info(f'Network error: {e}')
        raise

    except Exception as e:
        logger.info(f'Error in open_request: {e}')
        raise


def put_part(url, part_stream, part_size):
    headers = {'Content-Length': str(part_size)}

    try:
        response = requests.put(url, data=part_stream, headers=headers)
        response.raise_for_status()

    except requests.exceptions.RequestException as e:
        logger.info(f'Chunk transfer error: {e}')
        raise


def upload_file_pan123(file_path):
    client_id = 'z54ea40cw64p9ohrnr7h00a7dw851muc'
    client_secret = 'c9al8l0cw64p9ohru5bi00idz7o8662d'
    parent = 4144766
    token = ''
    # filename_suffix = os.path.basename(file_path).split('.')[-1]
    file_size = os.path.getsize(file_path)
    file_etag = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
    filename = os.path.basename(file_path)
    try:
        res_data = open_request('/api/v1/access_token', {'clientID': client_id, 'clientSecret': client_secret}, token)
        token = res_data['accessToken']
        res_data = open_request('/upload/v1/file/create', {
            'parentFileID': parent,
            'filename': filename,
            'etag': file_etag,
            'size': file_size
        }, token)

        if res_data['reuse']:
            logger.info('Fast upload successful')
            return filename

        upload_id = res_data['preuploadID']
        slice_size = res_data['sliceSize']

        res_data = open_request('/upload/v1/file/list_upload_parts', {'preuploadID': upload_id}, token)
        parts_map = {part['partNumber']: {'size': part['size'], 'etag': part['etag']} for part in
                     res_data.get('parts', [])}

        with open(file_path, 'rb') as file:
            for i in range(0, file_size, slice_size):
                part_num = i // slice_size + 1
                file.seek(i)
                temp_data = file.read(slice_size if i + slice_size < file_size else file_size - i)
                temp_size = len(temp_data)

                if temp_size == 0:
                    break

                temp_etag = hashlib.md5(temp_data).hexdigest()

                if part_num in parts_map and parts_map[part_num]['size'] == temp_size and parts_map[part_num][
                    'etag'] == temp_etag:
                    continue
                logger.info(f'part_num:{part_num}')
                res_data = open_request('/upload/v1/file/get_upload_url',
                                        {'preuploadID': upload_id, 'sliceNo': part_num}, token)
                put_part(res_data['presignedURL'], temp_data, temp_size)

        res_data = open_request('/upload/v1/file/upload_complete', {'preuploadID': upload_id}, token)
        if res_data['completed']:
            logger.info('Upload successful')
            return filename

        for j in range(MAX_RETRY_ATTEMPTS):
            time.sleep(5)
            res_data = open_request('/upload/v1/file/upload_async_result', {'preuploadID': upload_id}, token)
            if res_data['completed']:
                logger.info('Upload successful')
                return filename

        logger.info('Upload timed out')
        return

    except Exception as e:
        logger.info(f'Upload failed: {e}')
        if '文件名重复' in str(e):
            return filename
        return

def off_download_file_pan123(url):
    '''
    离线下载before_link
    :param url:
    :return:
    '''
    try:
        url = url.replace('https', 'http').replace('all2.jpg', 'silm.jpg')
        logger.info(f'离线资源：{url}')
        client_id = 'z54ea40cw64p9ohrnr7h00a7dw851muc'
        client_secret = 'c9al8l0cw64p9ohru5bi00idz7o8662d'
        r = requests.post('https://open-api.123pan.com/api/v1/access_token', headers={'Platform': 'open_platform'},
                          json={
                              'clientID': client_id,
                              'clientSecret': client_secret,
                          })
        token = r.json()['data']['accessToken']

        requests.post('https://open-api.123pan.com/api/v1/offline/download',
                      headers={'Platform': 'open_platform', 'Authorization': token}, json={
                'url': url,
                'fileName': os.path.basename(url),
            })
    except:
        pass


if __name__ == "__main__":
    # file_path = r'E:\soft\WPS Office 2019 专业版（政府版，已激活）-11.8.2.8053.exe'
    # logger.info(upload_file_pan123(file_path))
    # off_download_file_pan123('https://realpic.00123.fun/wx9aca4099daeda12f--7orKvP5GojgrvamGJyaX0dCKHnQml2B8MFuK_zqjgj0--oo2Yw5YnPYqdef_KgCtoypwHeBlI--5bff4bc6a5ef48195ca4878f1d0b2d9e--6.png-all2.jpg')
    upload_file_pan123(r'D:\36041981\349073873.x2m')